package persistencia.csv;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import persistencia.IAlmacen;
import persistencia.IEnsamblador;
import persistencia.IGondola;
import persistencia.IIngrediente;
import persistencia.IProducto;
import persistencia.compartido.Tipo;
import persistencia.excepciones.StringDeConexionIncompatible;
import persistencia.xml.GondolaXML;

import compartido.IEntidad;

public class AlmacenCSV implements IAlmacen {
	protected Map<String,GondolaCSV> gondolas;
	protected Map<String,IEnsamblador> ensambladores;
	protected Map<String,Tipo<? extends IEntidad>> tipos;
	protected File directorio;
	
	public AlmacenCSV() {
		gondolas = new HashMap<String, GondolaCSV>();
		ensambladores = new HashMap<String, IEnsamblador>();
		tipos = new HashMap<String, Tipo<? extends IEntidad>>();
		this.directorio = null;
	}

	@Override
	public boolean estaConectado() {
		return (this.directorio != null);
	}

	@Override
	public boolean esValido(String StringDeConexion) {
		return (StringDeConexion.matches("[^:]*") || StringDeConexion.matches(".+:.+"));
	}
	
	public void abrir(String StringDeConexion) throws StringDeConexionIncompatible {
		if (!estaConectado()) {
			File directorio = null;
			if (StringDeConexion.matches("[^:]*")) {
				directorio = new File(StringDeConexion);
			} else if (StringDeConexion.matches(".*:.*")) {
				String[] partes = StringDeConexion.split(":");
				if ((partes.length == 2) && (partes[0].compareTo("csv")==0))
					directorio = new File(partes[1]);
			}
			
			if ((directorio==null) || (!directorio.isDirectory()))
				throw new StringDeConexionIncompatible();

			this.directorio = directorio;
		}
		
	}
	
	public void cerrar() {
		if (estaConectado()) {
			this.guardar();
			this.gondolas.clear();
		}
	}
	
	@Override
	public IIngrediente crearIngrediente(String nombre, String valor) {
		IIngrediente ingrediente = null;
		if (!nombre.contains(","))
			ingrediente = new CampoCSV(nombre,valor);
		return ingrediente;
	}

	@Override
	public IProducto crearProducto(String campoID, String nombre, Tipo<IEntidad> tipo) {
		ProductoCSV nuevo = null;
		if (!nombre.contains(",")) {
			GondolaCSV gondola = gondolas.get(tipo.getNombre());
			EncabezadoCSV encabezado = null;
			if (gondola != null) {
				encabezado = gondola.getEncabezado();
				if (encabezado == null) {
					encabezado = new EncabezadoCSV(tipo.getNombre());
					encabezado.agregar(campoID);
				}
				nuevo = new ProductoCSV(encabezado,nombre);
			}
		}
		return nuevo;
	}

	@Override
	public IGondola crearGondola(Tipo<IEntidad> tipo) {
		GondolaCSV creada = gondolas.get(tipo.getNombre());
		
		if (creada == null) {
			IEnsamblador ens = ensambladores.get(tipo.getNombre());
			creada = new GondolaCSV(directorio, tipo, ens, this);
			gondolas.put(tipo.getNombre(),creada);
		}		
		return creada;
	}
	
	@Override
	public IGondola obtenerGondola(Tipo<IEntidad> tipo) {
		GondolaCSV existente = gondolas.get(tipo.getNombre());
		if (existente == null) {
			String nombreArchivo = directorio.getAbsolutePath()+"/"+tipo.getNombre()+".xml"; 
			File archivo = new File(nombreArchivo);
			if (archivo.exists()) {
				IEnsamblador ens = ensambladores.get(tipo.getNombre());
				existente = new GondolaCSV(directorio, tipo, ens, this);
				gondolas.put(tipo.getNombre(),existente);
			}
		}
		return existente;		
	}
	
	@Override
	public void guardar() {
		for (GondolaCSV gondola : gondolas.values())
			gondola.guardar();
	}

	@Override
	public void registrarEnsamblador(Tipo<IEntidad> entidades, IEnsamblador delegado) {
		ensambladores.put(entidades.getNombre(), delegado);
		tipos.put( entidades.getNombre(), entidades);
	}
}
